package net.brucecooper.mindmap.client;

import net.auroris.ColorPicker.client.Color;
import net.auroris.ColorPicker.client.ColorPicker;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

public class NodePropertiesPanel extends Composite {
    int row = 0;

    private NodeDataStore store;
    private int nodeID;
    private TextBox nameField;
    FlexTable panel = new FlexTable();
    ListBox nodeOrientationChooser;
    Button foregroundPicker;
    private ListBox decorationChooser;
    private Button backgroundPicker;
    private CheckBox collapsedField;

    public NodePropertiesPanel(NodeDataStore store, int nodeID) {
        this.store = store;
        
        nameField = new TextBox();
        
        addRow("Name", nameField);
        
        
        if (nodeID == NodeDataStore.ROOT_NODE) {
            // Add the Left/Right/Both Chooser.
            nodeOrientationChooser = new ListBox(false);
            nodeOrientationChooser.addItem(NodeOrientation.CENTER.toString());
            nodeOrientationChooser.addItem(NodeOrientation.LEFT.toString());
            nodeOrientationChooser.addItem(NodeOrientation.RIGHT.toString());
            
            addRow("Orientation", nodeOrientationChooser);
        }
        
        decorationChooser = new ListBox(false);
        // It is important that these be added in ordinal order, as that is used to select them
        decorationChooser.addItem(NodeOutlineStyle.CIRCLE.toString());
        decorationChooser.addItem(NodeOutlineStyle.UNDERLINE.toString());
        decorationChooser.addItem(NodeOutlineStyle.CLOUD.toString());
        addRow("Border", decorationChooser);

        foregroundPicker = createColorChooser("FG");
        backgroundPicker = createColorChooser("BG");
        com.google.gwt.user.client.ui.HorizontalPanel colorPanel = new com.google.gwt.user.client.ui.HorizontalPanel();
        colorPanel.add(foregroundPicker);
        colorPanel.add(backgroundPicker);
        addRow("Color", colorPanel);

        
        collapsedField = new CheckBox();
        addRow("Show collapsed initially", collapsedField);
        
        initWidget(panel);
        
        setNode(nodeID);
    }
    
    private void setButtonColor(Button b, String rgb, String defaultColor) {
        if (rgb == null)
            rgb = defaultColor;
        DOM.setStyleAttribute(b.getElement(), "backgroundColor", "#" + rgb);
        Color col = new Color();
        try {
            col.setHex(rgb);
            
            col.setHSV(col.getHue(), 100-col.getSaturation(), 100-col.getValue());
            
            DOM.setStyleAttribute(b.getElement(), "color", "#" + col.getHex());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    
    private String getButtonColor(Button button) {
        String current = DOM.getStyleAttribute(button.getElement(), "backgroundColor");
        
        String[] split = current.split("[\\(,\\)\\s]+");
        
        int r = Integer.parseInt(split[1]);
        int g = Integer.parseInt(split[2]);
        int b = Integer.parseInt(split[3]);
        Color c = new Color();
        try {
            c.setRGB(r, g, b);
        } catch (Exception e) {
            e.printStackTrace();
            return "000000";
        }
        
        return c.getHex();
        
    }
    
    private Button createColorChooser(String txt) {
        final Button colorPickerButton = new Button(txt);
        colorPickerButton.setStylePrimaryName("colorpicker");
        setButtonColor(colorPickerButton, "ff0000", null);
        
        colorPickerButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                PopupPanel db = new PopupPanel(true, true);
                ColorPicker cp = new ColorPicker() {
                    @Override
                    public void onChange(Widget w) {
                        super.onChange(w);
                        setButtonColor(colorPickerButton, this.getHexColor(), "000000");
                    }
                };
                String current = DOM.getStyleAttribute(colorPickerButton.getElement(), "backgroundColor");
                try {
                    cp.setHex(getButtonColor(colorPickerButton));
                } catch (Exception e) {
                    System.err.println("Can't set color to " + current.substring(1));
                    e.printStackTrace();
                }
                
                
                
                db.add(cp);
                
                db.showRelativeTo(colorPickerButton);
            }
        });
        return colorPickerButton;
    }
    
    
    private void addRow(String label, Widget comp) {
        panel.setWidget(row, 0, new Label(label));
        panel.setWidget(row++, 1, comp);
        
    }

    public void setNode(int nodeID) {
        this.nodeID = nodeID;
        nameField.setText(store.getNodeName(nodeID));
        if (nodeID == NodeDataStore.ROOT_NODE) {
            nodeOrientationChooser.setSelectedIndex(store.getRootNodeOrientation().ordinal());
        }
        decorationChooser.setSelectedIndex(store.getNodeOutline(nodeID).ordinal());
        
        setButtonColor(foregroundPicker, store.getNodeForeground(nodeID), "000000");
        setButtonColor(backgroundPicker, store.getNodeBackground(nodeID), "ffffff");
        
        collapsedField.setValue(store.isNodeCollapsedInitially(nodeID));
    }
    
    public void updateDataStore() {
        // TODO make these changes cumulative, rather than individual updates.  
        // TODO make sure that these chnges only propogate if they are real changes, in the model.
        store.setNodeName(nodeID, nameField.getText());
        if (nodeID == NodeDataStore.ROOT_NODE) {
            store.setRootNodeOrientation(NodeOrientation.values()[nodeOrientationChooser.getSelectedIndex()]);
        }
        store.setNodeOutline(nodeID, NodeOutlineStyle.values()[decorationChooser.getSelectedIndex()]);
        store.setNodeForeground(nodeID, getButtonColor(foregroundPicker));
        store.setNodeBackground(nodeID, getButtonColor(backgroundPicker));
        store.setNodeCollapsedInitially(nodeID, collapsedField.getValue());
    }
}
